﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using QFlow.Data;
using QFlow.Core;

namespace QFlow.Windows.Forms
{
    public partial class ReturnPurchaseOrder : Utils.BaseForm
    {
        PurchaseOrder _Order;
        List<PurchaseItem> _ReturnItems;
        BindingSource _BindingSource;

        public ReturnPurchaseOrder(PurchaseOrder sOrder, QFlowDbContext context)
            : base(context)
        {
            InitializeComponent();
            _Order = sOrder;
            _ReturnItems = new List<PurchaseItem>();
            foreach (var item in _Order.PurchaseItems)
            {
                if (context.ItemTypes.IsReturned(item.ItemTypeID))
                {
                    _ReturnItems.Add(item);
                }
            }

            txtID.Text = _Order.PurchaseOrderID.ToString();
            txtVendor.Text = _Order.Vendor.Name;
            txtPMethod.Text = _Order.PaymentMethod.PaymentMethod1;
            txtDiscountPercent.Text = _Order.DiscountPercent.ToString();

            gvItems.AutoGenerateColumns = false;
            gvItems.DataSource = _Order.PurchaseItems.Where(item => !this.Context.ItemTypes.IsReturned(item.ItemTypeID)).ToArray();

            _BindingSource = new BindingSource(_ReturnItems, string.Empty);
            gvReturn.AutoGenerateColumns = false;
            gvReturn.DataSource = _BindingSource;

            RefershForm();

            //Save the current Values
            Accounting.SaveCurrentValues();
        }

        private void ReturnItem(PurchaseItem item)
        {
            double maxQuantity = PurchaseOrderManager.GetMaximumReturnQuantity(item);
            if (!this.Context.ItemTypes.IsReceived(item.ItemTypeID))
            {
                MessageBox.Show(QFlow.Windows.Properties.Resources.MBReturnReceivedItemsOnly, QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
            else if (PurchaseOrderManager.CheckReturnItems(_ReturnItems, item) || maxQuantity <= 0)
            {
                MessageBox.Show(QFlow.Windows.Properties.Resources.MBAlreadyReturned, QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
            else
            {
                PurchaseItem returnedItem = PurchaseOrderManager.ReturnItem(item, maxQuantity, _Order.DiscountPercent);
                this._BindingSource.Add(returnedItem);
                RefershForm();
            }
        }

        private void RefershForm()
        {
            double withoutDiscount = PurchaseOrderManager.CalculateOrderValueWithoutDiscount(_Order);
            double afterDiscount = PurchaseOrderManager.CalculateOrderValue(_Order, _Order.DiscountPercent);


            txtValue.Text = withoutDiscount.ToString("F");
            txtAfterDiscount.Text = afterDiscount.ToString("F");

            txtDiscountValue.Text = (withoutDiscount - afterDiscount).ToString("F");
        }

        private void gvItems_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (gvItems.SelectedRows.Count > 0)
            {
                PurchaseItem item = gvItems.SelectedRows[0].DataBoundItem as PurchaseItem;
                ReturnItem(item);
            }
        }

        private void gvItems_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (gvItems.SelectedRows.Count > 0 && gvItems.Columns[e.ColumnIndex].Name == "btnReturn")
            {
                PurchaseItem item = gvItems.SelectedRows[0].DataBoundItem as PurchaseItem;
                ReturnItem(item);
            }
        }

        /// <summary>
        /// This event handler will check if the user enetered a valid quantity.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gvReturn_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (gvReturn.Columns[e.ColumnIndex].Name == "clmRQuantity")
            {
                PurchaseItem returnedItem = gvReturn.Rows[e.RowIndex].DataBoundItem as PurchaseItem;

                double maxQuantity = PurchaseOrderManager.GetAvailableReturnQuantity(returnedItem);
                double minQuantity = PurchaseOrderManager.GetMinimumReturnQuantity(returnedItem);

                double value = 0;
                if (double.TryParse(e.FormattedValue.ToString(), out value))
                {
                    if (value < minQuantity)
                    {
                        MessageBox.Show(QFlow.Windows.Properties.Resources.MBInvalidValue, QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        e.Cancel = true;
                    }
                    else if (value > maxQuantity)
                    {
                        MessageBox.Show(QFlow.Windows.Properties.Resources.MBIvalidQuantity, QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        e.Cancel = true;
                    }
                    else
                    {
                        if (returnedItem.Quantity != value)
                        {
                            returnedItem.Quantity = value;
                            RefershForm();
                        }
                        e.Cancel = false;
                    }
                }
                else e.Cancel = true;
            }
            else if (gvReturn.Columns[e.ColumnIndex].Name == "clmRUnitPrice")
            {
                PurchaseItem returnedItem = gvReturn.Rows[e.RowIndex].DataBoundItem as PurchaseItem;
                if (!returnedItem.IsAttached())
                {
                    double value = 0;
                    if (double.TryParse(e.FormattedValue.ToString(), out value))
                    {
                        if (value <= 0)
                        {
                            MessageBox.Show(QFlow.Windows.Properties.Resources.MBInvalidValue, QFlow.Windows.Properties.Resources.MBErrorCaption, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                            e.Cancel = true;
                        }
                        else
                        {
                            returnedItem.UnitPrice = value;
                            RefershForm();
                            e.Cancel = false;
                        }
                    }
                    else e.Cancel = true;
                }
            }
        }

        /// <summary>
        /// This event will make sure to disable the attcahed item from editing.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gvReturn_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            PurchaseItem returnedItem = gvReturn.Rows[e.RowIndex].DataBoundItem as PurchaseItem;
            if (returnedItem.IsAttached())
            {
                gvReturn.Rows[e.RowIndex].Cells["clmRUnitPrice"].ReadOnly = true;
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            double returnedValue = PurchaseOrderManager.SaveReturenedOrder(_Order, _ReturnItems);

            if (returnedValue > 0)
            {
                List<QFlow.Windows.Forms.PrintOrder.PrintItem> items = new List<PrintOrder.PrintItem>();
                foreach (var item in _Order.PurchaseItems)
                {
                    if (Context.ItemTypes.IsReturned(item.ItemTypeID))
                    {
                        QFlow.Windows.Forms.PrintOrder.PrintItem printItem = new PrintOrder.PrintItem()
                        {
                            ItemPrice = item.UnitPrice,
                            Name = item.Product.Name,
                            Quantity = item.Quantity
                        };
                        items.Add(printItem);
                    }
                }

                PrintOrder order = new PrintOrder()
                {
                    Date = _Order.Date,
                    OrderID = _Order.PurchaseOrderID.ToString(),
                    Title = "ارجاع طلبية شراء",
                    Value = returnedValue,
                    Items = items
                };
                OrderPrinter printer = new OrderPrinter();
                printer.PrintOrder(order);
            }

            Accounting.CommitCurentValues();
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void ReturnPurchaseOrder_FormClosing(object sender, FormClosingEventArgs e)
        {
            for (int i = _Order.PurchaseItems.Count - 1; i >= 0; i--)
            {
                var item = _Order.PurchaseItems[i];
                if (!item.IsAttached())
                {
                    Context.RemoveRecordFromInsertions(item);
                    _Order.PurchaseItems.Remove(item);
                }
            }
            Accounting.RestorValues();
            this.Context.DiscardChanges();
        }
    }
}
